package com.hellobike.haxing.modules.product.service.impl;

import cn.hutool.core.util.RandomUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelReader;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.read.metadata.ReadSheet;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
import com.google.common.base.Strings;
import com.hellobike.haxing.modules.product.constant.Constants;
import com.hellobike.haxing.modules.product.entity.*;
import com.hellobike.haxing.modules.product.exception.ProductException;
import com.hellobike.haxing.modules.product.mapper.*;
import com.hellobike.haxing.modules.product.model.ProductImportModel;
import com.hellobike.haxing.modules.product.model.SkuImportModel;
import com.hellobike.haxing.modules.product.model.SpuImportModel;
import com.hellobike.haxing.modules.product.service.IProductService;
import com.hellobike.haxing.modules.product.service.ISpuService;
import lombok.Cleanup;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @Description: SPU
 * @Author: haxing-boot
 * @Date: 2020-01-10
 * @Version: V1.0
 */
@Service
public class SpuServiceImpl extends ServiceImpl<SpuMapper, Spu> implements ISpuService {

    @Autowired
    private SpuMapper spuMapper;
    @Autowired
    private SkuMapper skuMapper;
    @Autowired
    private CategoryMapper categoryMapper;
    @Autowired
    private ProductMapper productMapper;
    @Autowired
    private UnitMapper unitMapper;
    @Autowired
    private TagMapper tagMapper;
    @Autowired
    private IProductService productService;

    @Override
    public IPage<Spu> page(Page<Spu> page, QueryWrapper<Spu> queryWrapper) {
        IPage<Spu> pageList = spuMapper.selectPage(page, queryWrapper);
        //填充分类名称
        fillCategoryNames(pageList.getRecords());

        return pageList;
    }

    //填充分类名称
    private void fillCategoryNames(List<Spu> spuList) {
        if (spuList != null && spuList.size() > 0) {
            Set<Long> categoryIds = new HashSet<>();
            spuList.forEach(spu -> {
                categoryIds.add(spu.getCategoryId1());
                categoryIds.add(spu.getCategoryId2());
                categoryIds.add(spu.getCategoryId3());
            });
            List<Category> categoryList = categoryMapper.selectBatchIds(categoryIds);
            Map<Long, String> categoryNameMap = categoryList.stream().collect(Collectors.toMap(Category::getId, Category::getName));
            spuList.forEach(spu -> {
                spu.setCategoryName1(categoryNameMap.get(spu.getCategoryId1()));
                spu.setCategoryName2(categoryNameMap.get(spu.getCategoryId2()));
                spu.setCategoryName3(categoryNameMap.get(spu.getCategoryId3()));
            });
        }
    }

    @Override
    public Spu getSpuDetail(Long id) {
        Spu spu = spuMapper.selectById(id);
        if (spu != null) {
            List<Sku> skus = skuMapper.selectList(new QueryWrapper<Sku>().lambda().eq(Sku::getSpuId, id));
            spu.setSkus(skus);
        }
        return spu;
    }

    @Transactional
    @Override
    public void saveSpu(Spu spu) throws ProductException {
        //检查重名
        if (checkSpuNameRepeat(spu.getSpuName(), null)) {
            throw new ProductException("[" + spu.getSpuName() + "]与系统中其他货品名称重复，请修改后再提交");
        }
        //设置SPU编码
        setSpuCode(spu);
        //保存SPU
        spuMapper.insert(spu);

        //设置SKU编码
        setSkuCodes(spu);
        //保存SKU列表
        for (Sku sku : spu.getSkus()) {
            sku.setSpuId(spu.getId());
            //若非标品未填69码，则将sku编码设置为69码
            if (spu.getStandard() == 0 && StringUtils.isBlank(sku.getBarcode())) {
                sku.setBarcode(sku.getSkuCode());
            }
            skuMapper.insert(sku);
        }
    }

    @Transactional
    @Override
    public void updateSpu(Spu spu) throws ProductException {
        //检查重名
        if (checkSpuNameRepeat(spu.getSpuName(), spu.getId())) {
            throw new ProductException("[" + spu.getSpuName() + "]与系统中其他货品名称重复，请修改后再提交");
        }
        //更新SPU
        spuMapper.updateById(spu);
        //同步规格属性到product表
        Product product = new Product();
        product.setId(spu.getId());
        product.setDimensions(spu.getDimensions());
        //同步商品说明到product表
        JSONArray specifications = new JSONArray();
        if (StringUtils.isNotBlank(spu.getNetContent())) {
            JSONObject jsonObject1 = new JSONObject();
            jsonObject1.put("name", "净含量");
            jsonObject1.put("value", spu.getNetContent());
            specifications.add(jsonObject1);
        }
        JSONObject jsonObject2 = new JSONObject();
        jsonObject2.put("name", "保存条件");
        jsonObject2.put("value", Strings.nullToEmpty(Constants.storeTypeMap.get(spu.getStoreType())));
        specifications.add(jsonObject2);
        JSONObject jsonObject3 = new JSONObject();
        jsonObject3.put("name", "保质期");
        jsonObject3.put("value", (spu.getShelfLife() == null ? "" : spu.getShelfLife()) + Strings.nullToEmpty(Constants.shelfLifeUnitMap.get(spu.getShelfLifeUnit())));
        specifications.add(jsonObject3);
        product.setSpecifications(specifications);
        productMapper.updateById(product);

        //设置SKU编码
        setSkuCodes(spu);
        //更新SKU列表
        List<Sku> oldSkus = skuMapper.selectList(new QueryWrapper<Sku>().lambda().eq(Sku::getSpuId, spu.getId()));
        List<Long> retainSkuIdList = new ArrayList<>();//依然保留的sku的id列表
        for (Sku sku : spu.getSkus()) {
            if (sku.getId() != null) {
                skuMapper.updateById(sku);
                retainSkuIdList.add(sku.getId());
            } else {
                sku.setSpuId(spu.getId());
                //若非标品未填69码，则将sku编码设置为69码
                if (spu.getStandard() == 0 && StringUtils.isBlank(sku.getBarcode())) {
                    sku.setBarcode(sku.getSkuCode());
                }
                skuMapper.insert(sku);
            }
        }
        //删除未保留的sku
        for (Sku oldSku : oldSkus) {
            if (!retainSkuIdList.contains(oldSku.getId())) {
                skuMapper.deleteById(oldSku.getId());
            }
        }
    }

    //检查货品名称是否重复
    private boolean checkSpuNameRepeat(String spuName, Long selfId) {
        Spu sameNameSpu = spuMapper.selectOne(new QueryWrapper<Spu>().lambda().eq(Spu::getSpuName, spuName));
        if (sameNameSpu != null && !Objects.equals(sameNameSpu.getId(), selfId)) {
            return true;
        }
        return false;
    }

    //SPU编码（12位）生成规则：第1位：商品类型（1生鲜2日杂），第2-4位：一级分类序列号，第5-7位：二级分类序列号，第8-10位：三级分类序列号，第11-15位：5位随机数
    private void setSpuCode(Spu spu) {
        if (!Strings.isNullOrEmpty(spu.getSpuCode())) {
            return;
        }
        Category category = categoryMapper.selectById(spu.getCategoryId2());
        String code = spu.getType() + category.getCode().substring(1, 10) + Strings.padStart(RandomUtil.randomInt(100000) + "", 5, '0');
        Integer count = spuMapper.selectCount(new QueryWrapper<Spu>().lambda().eq(Spu::getSpuCode, code));
        //编码重复，重新生成
        if (count > 0) {
            setSpuCode(spu);
            return;
        }
        spu.setSpuCode(code);
    }

    //SKU编码（19位）生成规则：15位SPU编码 + 4位随机数
    private void setSkuCodes(Spu spu) {
        String spuCode = spu.getSpuCode();
        Set<String> skuCodeSet = new HashSet<>();
        for (Sku sku : spu.getSkus()) {
            //已有编码，跳过
            if (!Strings.isNullOrEmpty(sku.getSkuCode())) {
                skuCodeSet.add(sku.getSkuCode());
                continue;
            }
            //生成不重复编码
            String skuCode;
            for (; ; ) {
                skuCode = spuCode + Strings.padStart(RandomUtil.randomInt(10000) + "", 4, '0');
                if (!skuCodeSet.contains(skuCode)) {
                    skuCodeSet.add(sku.getSkuCode());
                    sku.setSkuCode(skuCode);
                    break;
                }
            }
        }
    }

    //SPU表格下标
    private static final int SPU_SHEET_INDEX = 0;
    //SKU表格下标
    private static final int SKU_SHEET_INDEX = 1;
    //售卖信息表格下标
    private static final int PRODUCT_SHEET_INDEX = 2;

    @Transactional
    @Override
    public void importSpus(MultipartFile file) throws ProductException, IOException {
        if (!file.getOriginalFilename().endsWith(".xlsx")) {
            throw new ProductException("请上传后缀为.xlsx的excel文件");
        }
        LinkedHashSet<String> errorTips = new LinkedHashSet<>();
        LinkedHashMap<String, Spu> spuMap = new LinkedHashMap<>();
        LinkedHashMap<String, Product> productMap = new LinkedHashMap<>();
        //后台分类
        Map<String, Category> categoryMap = categoryMapper.getAll().stream().collect(Collectors.toMap(Category::getName, Function.identity()));
        //单位
        Map<String, Integer> unitMap = unitMapper.selectList(new QueryWrapper<>()).stream().collect(Collectors.toMap(Unit::getName, Unit::getId));
        //营销标签
        Map<String, Long> marketingTagMap = tagMapper.selectList(new QueryWrapper<Tag>().lambda().eq(Tag::getType, 2)).stream().collect(Collectors.toMap(Tag::getName, Tag::getId));

        @Cleanup InputStream in = file.getInputStream();
        @Cleanup("finish") ExcelReader excelReader = EasyExcel.read(in).build();

        final Splitter splitter = Splitter.on(',').trimResults().omitEmptyStrings();
        //读取SPU表格
        ReadSheet spuSheet = EasyExcel.readSheet(SPU_SHEET_INDEX).head(SpuImportModel.class).registerReadListener(new AnalysisEventListener<SpuImportModel>() {
            @Override
            public void invoke(SpuImportModel spuImportModel, AnalysisContext context) {
                String position = "<span style='color: red'>[表-" + (SPU_SHEET_INDEX + 1) + " 行-" + (context.getCurrentRowNum() + 1) + "] </span>";
                if (StringUtils.isBlank(spuImportModel.getSpuName()) || StringUtils.isBlank(spuImportModel.getType()) || StringUtils.isBlank(spuImportModel.getCategoryName1())
                        || StringUtils.isBlank(spuImportModel.getCategoryName2()) || StringUtils.isBlank(spuImportModel.getCategoryName3()) || StringUtils.isBlank(spuImportModel.getStockType())
                        || spuImportModel.getShelfLife() == null || StringUtils.isBlank(spuImportModel.getShelfLifeUnit())
                        || StringUtils.isBlank(spuImportModel.getPurchasePerson()) || StringUtils.isBlank(spuImportModel.getLogisticsStatus())
                        || StringUtils.isBlank(spuImportModel.getOriginType()) || StringUtils.isBlank(spuImportModel.getOrigin())) {
                    errorTips.add(position + "必填项不能为空；");
                }
                addErrorInfoIf(spuMap.get(spuImportModel.getSpuName()) != null, errorTips, position + "货品名称重复；");
                //类型转换
                Spu spu = new Spu();
                BeanUtils.copyProperties(spuImportModel, spu);
                //商品类型
                if (StringUtils.isNotBlank(spuImportModel.getType())) {
                    Integer type = Constants.spuTypeReverseMap.get(spuImportModel.getType());
                    addErrorInfoIf(type == null, errorTips, position + "非法的商品类型，请输入正确的商品类型：生鲜、日杂；");
                    spu.setType(type);
                }
                //分类
                Category category1 = null;
                if (StringUtils.isNotBlank(spuImportModel.getCategoryName1())) {
                    category1 = categoryMap.get(spuImportModel.getCategoryName1());
                    addErrorInfoIf(category1 == null || category1.getLevel() != 1, errorTips, position + "系统中不存在该一级分类；");
                }
                Category category2 = null;
                if (StringUtils.isNotBlank(spuImportModel.getCategoryName2())) {
                    category2 = categoryMap.get(spuImportModel.getCategoryName2());
                    addErrorInfoIf(category2 == null || category2.getLevel() != 2, errorTips, position + "系统中不存在该二级分类；");
                }
                Category category3 = null;
                if (StringUtils.isNotBlank(spuImportModel.getCategoryName3())) {
                    category3 = categoryMap.get(spuImportModel.getCategoryName3());
                    addErrorInfoIf(category3 == null || category3.getLevel() != 3, errorTips, position + "系统中不存在该三级分类；");
                }
                if (category1 != null && category2 != null && category3 != null) {
                    addErrorInfoIf(!category3.getParentId().equals(category2.getId()) || !category2.getParentId().equals(category1.getId()), errorTips, position + "分类父子关系错误；");
                    spu.setCategoryId1(category1.getId());
                    spu.setCategoryId2(category2.getId());
                    spu.setCategoryId3(category3.getId());
                }
                //备货类型
                if (StringUtils.isNotBlank(spuImportModel.getStockType())) {
                    Integer stockType = Constants.stockTypeReverseMap.get(spuImportModel.getStockType());
                    addErrorInfoIf(stockType == null, errorTips, position + "非法的备货类型，请输入正确的备货类型：非常备货、常备货；");
                    spu.setStockType(stockType);
                }
                //标品类型
                if (StringUtils.isNotBlank(spuImportModel.getStandard())) {
                    Integer standard = Constants.standardReverseMap.get(spuImportModel.getStandard());
                    addErrorInfoIf(standard == null, errorTips, position + "非法的标品类型，请输入正确的标品类型：非标品、标品；");
                    spu.setStandard(standard);
                }
                //计量单位
                if (StringUtils.isNotBlank(spuImportModel.getUnit())) {
                    Integer unit = unitMap.get(spuImportModel.getUnit());
                    addErrorInfoIf(unit == null, errorTips, position + "系统中不存在该计量单位；");
                    spu.setUnit(unit);
                }
                //存储类型
                if (StringUtils.isNotBlank(spuImportModel.getStoreType())) {
                    Integer storeType = Constants.storeTypeReverseMap.get(spuImportModel.getStoreType());
                    addErrorInfoIf(storeType == null, errorTips, position + "非法的存储类型，请输入正确的存储类型：常温、冷藏、冷冻；");
                    spu.setStoreType(storeType);
                }
                //规格属性
                JSONArray dimensions = new JSONArray();
                if (StringUtils.isNotBlank(spuImportModel.getDimensionNames())) {
                    List<String> dimensionNameList = splitter.splitToList(spuImportModel.getDimensionNames());
                    addErrorInfoIf(dimensionNameList.size() > 2, errorTips, position + "最多只能设置两种规格属性；");
                    for (String dimensionName : dimensionNameList) {
                        JSONObject dimension = new JSONObject();
                        dimension.put("name", dimensionName);
                        dimension.put("values", new JSONArray());
                        dimensions.add(dimension);
                    }
                }
                spu.setDimensions(dimensions);
                //保质期单位
                if (StringUtils.isNotBlank(spuImportModel.getShelfLifeUnit())) {
                    Integer shelfLifeUnit = Constants.shelfLifeUnitReverseMap.get(spuImportModel.getShelfLifeUnit());
                    addErrorInfoIf(shelfLifeUnit == null, errorTips, position + "非法的保质期单位，请输入正确的保质期单位：天、月、年；");
                    spu.setShelfLifeUnit(shelfLifeUnit);
                }
                //物流商品状态
                if (StringUtils.isNotBlank(spuImportModel.getLogisticsStatus())) {
                    Integer logisticsStatus = Constants.logisticsStatusReverseMap.get(spuImportModel.getLogisticsStatus());
                    addErrorInfoIf(logisticsStatus == null, errorTips, position + "非法的物流商品状态，请输入正确的物流商品状态：正常、淘汰、试新；");
                    spu.setLogisticsStatus(logisticsStatus);
                }
                //产地类型
                if (StringUtils.isNotBlank(spuImportModel.getOriginType())) {
                    Integer originType = Constants.originTypeReverseMap.get(spuImportModel.getOriginType());
                    addErrorInfoIf(originType == null, errorTips, position + "非法的产地类型，请输入正确的产地类型：国内、国外；");
                    spu.setOriginType(originType);
                }

                //暂时设置导入SPU全部为审核通过状态
                spu.setStatus(3);

                spu.setSkus(new ArrayList<>());
                spuMap.put(spu.getSpuName(), spu);
            }

            @Override
            public void doAfterAllAnalysed(AnalysisContext analysisContext) {
            }
        }).build();
        //读取SKU表格
        ReadSheet skuSheet = EasyExcel.readSheet(SKU_SHEET_INDEX).head(SkuImportModel.class).registerReadListener(new AnalysisEventListener<SkuImportModel>() {
            @Override
            public void invoke(SkuImportModel skuImportModel, AnalysisContext context) {
                String position = "<span style='color: orange'>[表-" + (SKU_SHEET_INDEX + 1) + " 行-" + (context.getCurrentRowNum() + 1) + "] </span>";
                if (StringUtils.isBlank(skuImportModel.getSpuName()) || skuImportModel.getPrice() == null || skuImportModel.getCommissionRate() == null
                        || skuImportModel.getCogsPrice() == null) {
                    errorTips.add(position + "必填项不能为空；");
                }
                Spu spu = spuMap.get(skuImportModel.getSpuName());
                addErrorInfoIf(spu == null, errorTips, position + "没有对应的SPU信息，请检查货品名称是否填写正确；");
                if (spu != null) {
                    addErrorInfoIf(Objects.equals(spu.getStandard(), 1) && StringUtils.isBlank(skuImportModel.getBarcode()), errorTips, position + "此SKU对应的SPU是标品，故必须填写商品码（69码）；");
                    //类型转换
                    Sku sku = new Sku();
                    BeanUtils.copyProperties(skuImportModel, sku);
                    //规格属性
                    JSONArray dimensions = spu.getDimensions();
                    List<String> dimensionValueList = new ArrayList<>();
                    if (StringUtils.isNotBlank(skuImportModel.getDimensionValues())) {
                        dimensionValueList = splitter.splitToList(skuImportModel.getDimensionValues());
                    }
                    if (dimensions.size() != dimensionValueList.size()) {
                        errorTips.add(position + "规格属性值的数目与对应SPU的规格属性种类数目不一致；");
                    } else {
                        //生成SKU规格属性
                        JSONObject dimensionValues = null;
                        if (dimensions.size() > 0) {
                            dimensionValues = new JSONObject();
                            for (int i = 0; i < dimensions.size(); i++) {
                                String dimensionName = dimensions.getJSONObject(i).getString("name");
                                String dimensionValue = dimensionValueList.get(i);
                                dimensionValues.put(dimensionName, dimensionValue);
                                if (!dimensions.getJSONObject(i).getJSONArray("values").contains(dimensionValue)) {
                                    dimensions.getJSONObject(i).getJSONArray("values").add(dimensionValue);
                                }
                            }
                        }
                        sku.setDimensionValues(dimensionValues);
                        //检查SKU规格属性是否重复
                        boolean isDimensionValuesRepeat = false;
                        for (Sku otherSku : spu.getSkus()) {
                            if (otherSku.getDimensionValues() == null && sku.getDimensionValues() == null) {
                                isDimensionValuesRepeat = true;
                                break;
                            }
                            if (otherSku.getDimensionValues() != null && sku.getDimensionValues() != null) {
                                boolean isSameDimensionValues = true;
                                for (String dimensionName : sku.getDimensionValues().keySet()) {
                                    if (!sku.getDimensionValues().getString(dimensionName).equals(otherSku.getDimensionValues().getString(dimensionName))) {
                                        isSameDimensionValues = false;
                                        break;
                                    }
                                }
                                if (isSameDimensionValues) {
                                    isDimensionValuesRepeat = true;
                                    break;
                                }
                            }
                        }
                        addErrorInfoIf(isDimensionValuesRepeat, errorTips, position + "规格属性与对应SPU下其他SKU重复；");

                        spu.getSkus().add(sku);
                    }
                }
            }

            @Override
            public void doAfterAllAnalysed(AnalysisContext analysisContext) {
            }
        }).build();
        //读取售卖信息表格
        ReadSheet productSheet = EasyExcel.readSheet(PRODUCT_SHEET_INDEX).head(ProductImportModel.class).registerReadListener(new AnalysisEventListener<ProductImportModel>() {
            @Override
            public void invoke(ProductImportModel productImportModel, AnalysisContext context) {
                String position = "<span style='color: deeppink'>[表-" + (PRODUCT_SHEET_INDEX + 1) + " 行-" + (context.getCurrentRowNum() + 1) + "] </span>";
                if (StringUtils.isBlank(productImportModel.getSpuName()) || StringUtils.isBlank(productImportModel.getTitle()) || StringUtils.isBlank(productImportModel.getAvailableType())) {
                    errorTips.add(position + "必填项不能为空；");
                }
                Spu spu = spuMap.get(productImportModel.getSpuName());
                addErrorInfoIf(spu == null, errorTips, position + "没有对应的SPU信息，请检查货品名称是否填写正确；");
                if (spu != null) {
                    addErrorInfoIf(productMap.get(productImportModel.getSpuName()) != null, errorTips, position + "重复数据，一个货品只能有一行售卖信息；");

                    Product product = new Product();
                    BeanUtils.copyProperties(productImportModel, product);

                    //适用点位类型
                    if (StringUtils.isNotBlank(productImportModel.getAvailableType())) {
                        Integer availableType = Constants.availableTypeReverseMap.get(productImportModel.getAvailableType());
                        addErrorInfoIf(availableType == null, errorTips, position + "非法的适用点位类型，请输入正确的适用点位类型：全部点位；");
                        product.setAvailableType(availableType);
                    }
                    //营销标签
                    JSONArray marketingTags = new JSONArray();
                    if (StringUtils.isNotBlank(productImportModel.getMarketingTags())) {
                        List<String> marketingTagList = splitter.splitToList(productImportModel.getMarketingTags());
                        addErrorInfoIf(marketingTagList.size() > 3, errorTips, position + "最多只能添加3个营销标签；");
                        for (String tagName : marketingTagList) {
                            Long tagId = marketingTagMap.get(tagName);
                            addErrorInfoIf(tagId == null, errorTips, position + "营销标签‘" + tagName + "’在系统中不存在；");
                            marketingTags.add(tagId);
                        }
                    }
                    product.setMarketingTags(marketingTags);
                    //商品说明，改成从spu信息中获取
//                    JSONArray specifications = new JSONArray();
//                    Splitter splitter1 = Splitter.on("&&&").trimResults().omitEmptyStrings();
//                    Splitter splitter2 = Splitter.on("===").trimResults().omitEmptyStrings();
//                    if (StringUtils.isNotBlank(productImportModel.getSpecifications())) {
//                        boolean formatError = false;
//                        List<String> specificationList = splitter1.splitToList(productImportModel.getSpecifications());
//                        for (String specification : specificationList) {
//                            List<String> nameValue = splitter2.splitToList(specification);
//                            if (nameValue.size() != 2) {
//                                formatError = true;
//                                break;
//                            } else {
//                                JSONObject jsonObject = new JSONObject();
//                                jsonObject.put("name", nameValue.get(0));
//                                jsonObject.put("value", nameValue.get(1));
//                                specifications.add(jsonObject);
//                            }
//                        }
//                        addErrorInfoIf(formatError, errorTips, position + "请按照正确的格式填写商品说明：以'&&&'连接各说明项，以'==='连接说明标题和内容；");
//                    }
//                    product.setSpecifications(specifications);

                    productMap.put(productImportModel.getSpuName(), product);
                }
            }

            @Override
            public void doAfterAllAnalysed(AnalysisContext analysisContext) {
            }
        }).build();

        excelReader.read(spuSheet, skuSheet, productSheet);

        if (errorTips.size() > 0) {
            throw new ProductException(Joiner.on("<br/>").join(errorTips));
        }
        //保存入库
        for (Spu spu : spuMap.values()) {
            //保存SPU和SKU
            saveSpu(spu);
            //保存product
            Product product = productMap.get(spu.getSpuName());
            if (product != null) {
                product.setSpuId(spu.getId());
                productService.saveProduct(product);
            }
        }
    }

    private void addErrorInfoIf(boolean condition, LinkedHashSet<String> errorTips, String errorInfo) {
        if (condition) {
            errorTips.add(errorInfo);
        }
    }
}
